home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / misc / amigem.lha / amigem / exec / signals.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-22  |  3.1 KB  |  140 lines

  1. #include <exec/tasks.h>
  2. #include <exec/memory.h>
  3. #include <exec/semaphores.h>
  4. #include <exec/devices.h>
  5. #include <exec/io.h>
  6. #include <amigem/machine.h>
  7. #include <clib/_exec.h>
  8. #include "exec.h"
  9.  
  10. #include <amigem/fd_lib.h>
  11. #define LIBBASE struct ExecBase *SysBase
  12.  
  13. #define FallAsleep    Private_1
  14. #define AddContext    Private_3
  15. #define DISPATCH() Cause(SysBase->SoftDispatch)
  16.  
  17. FD1(55,BYTE,AllocSignal,long signum,D0)
  18. {
  19.   ULONG *mask;
  20.   mask=&SysBase->ThisTask->tc_SigAlloc;
  21.   if(signum<0)
  22.   {
  23.     ULONG mask1=*mask,mask2=1;
  24.     for(signum=0;signum<sizeof(ULONG)*BITSPERBYTE;signum++)
  25.     {
  26.       if(!(mask1&mask2))
  27.       {
  28.         *mask|=mask2;
  29.         return signum;
  30.       }
  31.       mask2<<=1;
  32.     }
  33.     return -1;
  34.   }
  35.   else
  36.   {
  37.     if(*mask&1<<signum)
  38.       return -1;
  39.     *mask|=1<<signum;
  40.     return signum;
  41.   }
  42. }
  43.       
  44. FD1(56,void,FreeSignal,long signum,D0)
  45. {
  46.   if(signum>=0)
  47.     SysBase->ThisTask->tc_SigAlloc&=~(1<<signum);
  48. }
  49.  
  50. FD2(51,ULONG,SetSignal,ULONG new,D0,ULONG mask,D1)
  51. {
  52.   volatile ULONG *sig;
  53.   ULONG old;
  54.   Disable();
  55.     sig=&SysBase->ThisTask->tc_SigRecvd;
  56.     old=*sig;
  57.     *sig=(old&~mask)|(new&mask);
  58.   Enable();
  59.   return old;
  60. }
  61.  
  62. FD2(52,ULONG,SetExcept,ULONG newSignals,D0,ULONG signalMask,D1)
  63. {
  64.   struct Task *me;
  65.   ULONG old;
  66.   me=SysBase->ThisTask;
  67.   Disable();
  68.     old=me->tc_SigExcept;
  69.     me->tc_SigExcept=(old&~signalMask)|(newSignals&signalMask);
  70.     if(me->tc_SigExcept&me->tc_SigRecvd)
  71.     { me->tc_State=TS_EXCEPT;
  72.       DISPATCH(); }
  73.   Enable();
  74.   return old;
  75. }
  76.  
  77. void __ExceptionMode();
  78.  
  79. FD2(54,void,Signal,struct Task *task,A1,ULONG sigs,D0)
  80. {
  81.   Disable();
  82.     task->tc_SigRecvd|=sigs;
  83.     if(task->tc_SigExcept&task->tc_SigRecvd)
  84.     {
  85.       if(task==SysBase->ThisTask)
  86.       { SysBase->ThisTask->tc_State=TS_EXCEPT;
  87.         DISPATCH(); }
  88.       else
  89.       {
  90.         sigs=task->tc_SigExcept&task->tc_SigRecvd;
  91.         task->tc_SigRecvd &=~sigs;
  92.         task->tc_SigExcept&=~sigs;
  93.         task->tc_SPReg=AddContext(task->tc_SPReg,&__ExceptionMode,(APTR)sigs);
  94.         task->tc_State=TS_READY; /* two to Tolouse */
  95.         Remove(&task->tc_Node);
  96.         Enqueue(&SysBase->TaskReady,&task->tc_Node);
  97.         DISPATCH();
  98.       }
  99.     }else if(task!=SysBase->ThisTask&&task->tc_SigRecvd&task->tc_SigWait)
  100.     {
  101.       task->tc_State=TS_READY;
  102.       Remove(&task->tc_Node);
  103.       Enqueue(&SysBase->TaskReady,&task->tc_Node);
  104.       DISPATCH();
  105.     }
  106.   Enable();
  107. }
  108.  
  109. FD1(53,ULONG,Wait,ULONG sigs,D0)
  110. {
  111.   ULONG rcvd;
  112.   struct Task *me;
  113.   me=SysBase->ThisTask;
  114.   Disable();
  115.     while(!(me->tc_SigRecvd&sigs))
  116.     {
  117.       me->tc_SigWait=sigs;
  118.       me->tc_TDNestCnt=SysBase->TDNestCnt;
  119.       SysBase->TDNestCnt=-1;
  120.       me->tc_IDNestCnt=SysBase->IDNestCnt;
  121.       SysBase->IDNestCnt=0;
  122.       me->tc_State=TS_WAIT;
  123.       Enable();
  124.         DISPATCH();
  125.       Disable();
  126.       while(me->tc_State==TS_WAIT)
  127.       { /* Dispatcher could not put me asleep (no ready tasks :-) ) */
  128.         Enable();
  129.           FallAsleep();
  130.         Disable();
  131.       }
  132.       SysBase->IDNestCnt=me->tc_IDNestCnt;
  133.       SysBase->TDNestCnt=me->tc_TDNestCnt;
  134.     }
  135.     rcvd=me->tc_SigRecvd;
  136.     me->tc_SigRecvd&=~sigs;
  137.   Enable();
  138.   return rcvd;
  139. }
  140.